<?php
abstract class Module_Impl_Abstarct_Select implements Module_Interface_Select {
	/**
	 * @var Zend_Db_Adapter_Pdo_Mysql
	 */
	protected $_dbAdapter = null;
	
	protected $_tablename = null;
	
	protected $_objectname = null;
	
	const SQLARRAY_OPTION_TABLENAME = 'tablename';
	const SQLARRAY_OPTION_WHERE = 'where';
	const SQLARRAY_OPTION_ORDERBY = 'order';
	const SQLARRAY_OPTION_GROUPBY = 'group';
	const SQLARRAY_OPTION_SELECT = 'select';
	const SQLARRAY_OPTION_COUNT = 'isForCount';
	const SQLARRAY_OPTION_LIMIT = 'limit';
	const SQLARRAY_OPTION_OFFSET = 'offset';
	/**
	 * Constructor
	 * @return void
	 */
	protected function __construct() {
		$this->_dbAdapter = Zend_Db_Table::getDefaultAdapter ();
	}
	/**
	 * 将数组转化为符合$sqlArray['where']要求的数组
	 * @return array
	 */
	protected function _getWhereArray($values, $isAllowNullValue = false) {
		if (is_array ( $values )) {
			foreach ( $values as $key => $value ) {
				if ($value == Config_Table::DEFAULT_NULL_VALUE) {
					unset ( $values [$key] );
					continue;
				}
				if ($value == - 99) {
					unset ( $values [$key] );
					continue;
				}
				if (! $isAllowNullValue and empty ( $value )) {
					unset ( $values [$key] );
					continue;
				}
			}
			$whereArray = array ();
			foreach ( $values as $field => $value ) {
				$fields = explode ( '.', $field );
				$fields_count = count ( $fields );
				if ($fields_count == 1) {
					$field = $this->_tablename . '.' . $field;
					$_field_last = $fields [0];
				} else {
					$_field_last = $fields [count ( $fields ) - 1];
				}
				if (is_array ( $value )) {
					$value = isset ( $value [$_field_last] ) ? $value [$_field_last] : NULL;
				}
				$whereArray [$field . '= ?'] = $value;
			}
			return $whereArray;
		}
		return null;
	}
	
	protected $_options = array();
	
	/**
	 * 
	 * @return Module_Impl_Abstarct_Select
	 */
	public function setOptions($options = array()){
		$this->_options = $options;
		return $this;
	}
	
	/**
	 * 
	 * @return array
	 */
	protected function _getSqlArray($options = array()) {
		$options = array_merge($options,$this->_options);
		$tablename = isset ( $options [self::SQLARRAY_OPTION_TABLENAME] ) ? $options [self::SQLARRAY_OPTION_TABLENAME] : $this->_tablename;
		$sqlArray ['tablename'] = $tablename;
		$whereArray = isset ( $options [self::SQLARRAY_OPTION_WHERE] ) ? $options [self::SQLARRAY_OPTION_WHERE] : null;
		if (! empty ( $whereArray )) {
			$sqlArray ['where'] = $whereArray;
		}
		$orderby = isset ( $options [self::SQLARRAY_OPTION_ORDERBY] ) ? $options [self::SQLARRAY_OPTION_ORDERBY] : null;
		
		$isForCount = isset ( $options [self::SQLARRAY_OPTION_COUNT] ) ? $options [self::SQLARRAY_OPTION_COUNT] : null;
		if (! empty ( $orderby ) and empty ( $isForCount )) {
			$sqlArray ['order'] = $orderby;
		}
		$sql_select = isset ( $options [self::SQLARRAY_OPTION_SELECT] ) ? $options [self::SQLARRAY_OPTION_SELECT] : '*';
		$sqlArray ['select'] = $sql_select;
		return $sqlArray;
	}
	
	public function getById($id,$options = array()) {
		try {
			$data = $this->getByField ( "id", $id, $options, true);
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
	
	public function getByField($field, $value, $options = array(),$onlyOne = true) {
		try {
			$data = $this->getByFieldValueArray ( array ($field => $value ), $options,$onlyOne );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
	
	public function getByFieldValueArray($fieldValues, $options = array(), $onlyOne = true) {
		try {
			if (empty ( $fieldValues )) {
				return null;
			}
			$data = $this->getData ( $this->_getWhereArray ( $fieldValues ), $options, $onlyOne );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
		
	public function getData($whereArray = null, $options = array(), $onlyOne = false) {
		try {
			$options [self::SQLARRAY_OPTION_WHERE] = $whereArray;
			$sqlArray = $this->_getSqlArray ( $options );
			$limit = isset ( $options [self::SQLARRAY_OPTION_LIMIT] ) ? $options [self::SQLARRAY_OPTION_LIMIT] : null;
			$offset = isset ( $options [self::SQLARRAY_OPTION_OFFSET] ) ? $options [self::SQLARRAY_OPTION_OFFSET] : null;
			$data = $this->_getData ( $sqlArray, $onlyOne, $limit, $offset, $this->_objectname );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
	
	public function getCounts($whereArray = null) {
		try {
			$options [self::SQLARRAY_OPTION_WHERE] = $whereArray;
			$options [self::SQLARRAY_OPTION_COUNT] = true;
			$sqlArray = $this->_getSqlArray ( $options );
			$mysqlDb = DbOperation_Select::getInstance ();
			$counts = $mysqlDb->getCounts ( $sqlArray );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $counts;
	}
	/**
	 * 
	 * 
	 * @use
	 * @access
	 * @param array $whereArray 
	 * @param Object_PageInfo $pageInfo
	 * @return array
	 */
	public function getDataByPageInfo($whereArray, $pageInfo) {
		try {
			$options [self::SQLARRAY_OPTION_ORDERBY] = $pageInfo->getOrderby ();
			$options [self::SQLARRAY_OPTION_LIMIT] = $pageInfo->getLimit ();
			$options [self::SQLARRAY_OPTION_OFFSET] = $pageInfo->getOffset ();
			$data = $this->getData ( $whereArray, $options, false );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
	public function getHtmlByPageInfo($pageInfo) {
		try {
			$mysqlDb = Htmlhelper_Page::getInstance ()->setPageInfo ( $pageInfo );
			$data = $mysqlDb->getPageHtml ();
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
	public function getFormatHtmlByPageInfo($pageInfo) {
		try {
			$mysqlDb = Htmlhelper_Page::getInstance ()->setPageInfo ( $pageInfo );
			$data = $mysqlDb->getPageFormatHtml ();
		} catch ( Exception $e ) {
			throw $e;
		}
		return $data;
	}
	
	protected function _getData($sqlArray, $onlyOne = false, $limit = null, $offset = null, $classname) {
		$mysqlDb = DbOperation_Select::getInstance ();
		//Zend_Debug::dump($mysqlDb->getSql($sqlArray));
		$rows = $mysqlDb->getData ( $sqlArray, $limit, $offset, $classname );
		if (empty ( $rows )) {
			return null;
		}
		if ($onlyOne) {
			if (empty ( $rows [0] )) {
				return null;
			}
			return $rows [0];
		} else {
			return $rows;
		}
	}
}